package com.xm.test.redislock;


import com.xm.component.redislock.annotation.Lock;
import com.xm.component.redislock.annotation.LockKey;
import com.xm.component.redislock.core.GetRedisLockException;
import com.xm.component.redislock.core.RedisLock;
import com.xm.component.redislock.core.RedisLockComponent;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("redislock")
@Slf4j
public class RedisLockTestController {

    @Resource
    private RedisLockComponent redisLockComponent;

    @RequestMapping("annotationTest/sayHello1")
    @Lock(keyPrefix = "HELLO:")
    public String sayHello1(@RequestParam("name") @LockKey String name) throws InterruptedException {
        Thread.sleep(7000);
        return "hello " + name;
    }


    /**
     * 手动方式获取redis锁
     *
     * @param name
     * @return
     */
    @RequestMapping("annotationTest/sayHello2")
    public String sayHello2(@RequestParam("name") @LockKey String name) {
        try {
            return redisLockComponent.execOnLocked("HELLO:" + name, () -> {
                try {
                    Thread.sleep(7000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return "hello " + name;
            });
        } catch (GetRedisLockException e) {
            log.error("sayHello异常：", e);
            return "服务繁忙";
        }

    }

    /**
     * @param name
     * @return
     */
    @RequestMapping("manualTest/sayHello3")
    public String sayHello3(@RequestParam("name") String name) throws InterruptedException {
        RedisLock lock = null;
        try {
            lock = redisLockComponent.tryLockElseException("HELLO:" + name);
            Thread.sleep(7000);
            return "hello " + name;
        } catch (GetRedisLockException e) {
            log.error("sayHello异常：", e);
            return "服务繁忙";
        } finally {
            redisLockComponent.unlock(lock);
        }
    }


    /**
     * User{@linkplain com.xm.component.redislock.core.RedisLockKey}接口
     */
    @PostMapping("annotationTest/createOrder")
    @Lock(keyPrefix = "HELLO:")
    public String sayHello4(@RequestBody @LockKey User user) throws InterruptedException {
        Thread.sleep(7000);
        return "hello " + user.getName();
    }


}
